package com.tdcy.sys.util.shiro;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import com.tdcy.framework.util.StringUtils;
import com.tdcy.sys.dao.IUserDAO;
import com.tdcy.sys.dao.IUserKindDAO;
import com.tdcy.sys.dao.IUserRoleDAO;
import com.tdcy.sys.dao.eo.MenuEO;
import com.tdcy.sys.dao.eo.RolesEO;
import com.tdcy.sys.dao.eo.UserEO;
import com.tdcy.sys.dao.eo.UserKindEO;
import com.tdcy.sys.service.IMenuSvc;
import com.tdcy.sys.service.IRolesSvc;
import com.tdcy.sys.service.IUserSvc;
import com.tdcy.sys.service.bean.LoginCo;
import com.tdcy.sys.service.bean.LoginInfoBean;
import com.tdcy.sys.util.MenuUtils;

public class AccountAuthorizationRealm extends AuthorizingRealm {
	@Resource
	private IUserSvc userService;

	@Resource
	private IMenuSvc menuService;

	@Resource
	private IRolesSvc roleService;

	@Resource
	IUserKindDAO userkindDAO;

	@Resource
	IUserDAO userDao;

	@Resource
	IUserSvc userSvc;

	@Resource
	IUserRoleDAO userrolesDAO;

	@Resource
	IMenuSvc menuSvc;

	private String name = "AccountAuthorizationRealm";

	public String getName() {
		return name;
	}

	/**
	 * 登录认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		LoginCo co = token.getLoginCo();
		UserEO userEO = userSvc.login(co);

		Integer userKind = userEO.getUserKind();
		UserKindEO userKindEO = userkindDAO.findByPrimaryKey(UserKindEO.class, userKind);

		String loginSql = userKindEO.getLoginSql();
		List<Object> paramList = new ArrayList<Object>();

		String params = userKindEO.getParams();
		if (!StringUtils.isEmpty(params)) {
			String[] ps = params.split(",");
			String loginUser = co.getLoginUser();
			for (int i = 0; i < ps.length; i++) {
				paramList.add(loginUser);
			}
		}
		List<Map> logininfo = userDao.execSqlQueryToMap(loginSql, StringUtils.toArray(paramList));
		if (logininfo == null || logininfo.size() <= 0) {
			throw new AuthenticationException("用户信息不存在");
		}

		Map fmap = logininfo.get(0);
		String loginUserField = (String) fmap.get(userKindEO.getLoginType());
		co.setLoginUser(loginUserField);

		LoginInfoBean loginInfo = token.getLoginInfo();
		loginInfo.setLoginDetail(fmap);
		loginInfo.setUserEO(userEO);
		loginInfo.setUserKindEO(userKindEO);

		String credentials = co.getPassword();
		SimpleAuthenticationInfo si = new SimpleAuthenticationInfo(authcToken, credentials, getName());
		return si;
	}

	/**
	 * 权限认证
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		UsernamePasswordToken token = (UsernamePasswordToken) principals.getPrimaryPrincipal();
		LoginInfoBean loginInfo = token.getLoginInfo();

		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

		// 增加定义配置角色
		List<RolesEO> roleList = userrolesDAO.getRolesByUserId(loginInfo.getUserEO().getUserId());
		info.addRole("lxadmin");

		for (RolesEO role : roleList) {
			if (!StringUtils.isEmpty(role.getRoleCode())) {
				info.addRole(role.getRoleCode());
			}
		}

		// 增加自定义配置权限
		List<MenuEO> rightlist = new ArrayList<MenuEO>();
//		if (UserUtils.isAdminRole(roleList)) {
//			List<MenuEO> menus = menuSvc.getAllRight();
//			for (MenuEO me : menus) {
//				rightlist.add(me);
//			}
//		} else {
			for (RolesEO re : roleList) {
				List<MenuEO> menu = menuSvc.getAllRightsByRoleId(re.getRoleId());
				rightlist.addAll(menu);
			}
//		}
		List<MenuEO> retlist = MenuUtils.removeDupMenu(rightlist);
		for (MenuEO menu : retlist) {
			if (!StringUtils.isEmpty(menu.getPermissionCode())) {
				System.out.println(menu.getPermissionCode());
				info.addStringPermission(menu.getPermissionCode());
			}
		}

		loginInfo.setRoleEOList(roleList);
		loginInfo.setRightInfoEOList(retlist);

		return info;
	}

}
